#include "inventory.h"
#include <QResizeEvent>
#include <QDebug>

#define BUTTON_SIZE 60

Inventory::Inventory(QWidget *parent) :
   QWidget(parent),
   mSelectionID(0),
   mNumButtons(0),
   mPulsateScale(1.0),
   mPulsateCountUp(true)
{
   mPulsateTimer = new QTimer(this);
   connect(mPulsateTimer, SIGNAL(timeout()), this, SLOT(tick()));
   mPulsateTimer->setInterval(30); // FIXME, tie to client RENDER_RATE_IN_MS
   mPulsateTimer->start();
}


Inventory::~Inventory()
{
}

void Inventory::resizeEvent(QResizeEvent *event)
{
   QWidget::resizeEvent(event);
   repositionButtons();
}


void Inventory::addButton(const quint32 id, const EntityBaseStats &stats)
{
   InventoryButton *button = new InventoryButton(id, this);
   button->setCheckable(true);
   button->setMinimumSize(BUTTON_SIZE, BUTTON_SIZE);
   button->setMaximumSize(BUTTON_SIZE, BUTTON_SIZE);

   int r = (mNumButtons/(width()/BUTTON_SIZE)) * BUTTON_SIZE;
   int c = (mNumButtons%(width()/BUTTON_SIZE)) * BUTTON_SIZE;
   mNumButtons++;

   button->setGeometry(c,r,BUTTON_SIZE,BUTTON_SIZE);
   button->setEntityStats(stats);

   connect(button, SIGNAL(clicked()), this, SLOT(onInvButton()));

   EntitySquadType *squad = new EntitySquadType;
   squad->id = id;
   squad->isDeployed = false;
   squad->size = 1;
   squad->cost = 0;
   squad->stats = stats;
   mSquadMap.insert(id, squad);
   mButtonMap.insert(id, button);

   button->show();

   // Resize widget underneath in case we need scroll bars
   setMinimumHeight(r+BUTTON_SIZE);

   //setSelection(id, false);
}

void Inventory::removeSelection()
{
   if (mSelectionID)
   {
      EntitySquadType *squad = mSquadMap.take(mSelectionID);
      if (squad && !squad->isDeployed)
      {
         delete squad;
         InventoryButton *ib = mButtonMap.take(mSelectionID);
         delete ib;
         mNumButtons--;
         repositionButtons();
      }
   }

   clearSelection();
}


void Inventory::incSelection()
{
   if (mSelectionID)
   {
      EntitySquadType *squad =  mSquadMap.value(mSelectionID);
      if (squad && !squad->isDeployed)
      {
         squad->size++;
         InventoryButton *b = mButtonMap.value(mSelectionID);
         if (b)
            b->setCount(squad->size);
      }
   }
}


void Inventory::decSelection()
{
   if (mSelectionID)
   {
      EntitySquadType *squad =  mSquadMap.value(mSelectionID);
      if (squad && !squad->isDeployed && squad->size>1)
      {
         squad->size--;
         InventoryButton *b = mButtonMap.value(mSelectionID);
         if (b)
            b->setCount(squad->size);
      }
   }
}


void Inventory::onInvButton()
{
   InventoryButton *invButton = ((InventoryButton*)sender());
   if (invButton)
      setSelection(invButton->id());
}


void Inventory::clearSelection()
{
   setSelection(0);
}


EntityBaseStats Inventory::selectionStats()
{
   EntityBaseStats stats;
   if (mSelectionID > 0)
   {
      EntitySquadType *squad = mSquadMap.value(mSelectionID);
      if (squad)
         stats = squad->stats;
   }
   return stats;
}


void Inventory::setSelection(const quint32 id, const bool emitSignal)
{
   qDebug() << "Inventory::setSelection" << id;
   mSelectionID = id;
   // Deselect remaining buttons
   foreach (QObject *obj, children())
   {
      InventoryButton *button = dynamic_cast<InventoryButton*>(obj);
      if (button)
         button->setChecked((button->id() == mSelectionID));
   }
   if (emitSignal)
      emit newSelection(mSelectionID);
}


bool Inventory::isSelectionModifiable()
{
   if (mSelectionID > 0)
   {
      EntitySquadType *squad = mSquadMap.value(mSelectionID);
      return (squad && !squad->isDeployed);
   }
   return false;
}


bool Inventory::setSelectionStats(const EntityBaseStats &stats)
{
   EntitySquadType *squad =  mSquadMap.value(mSelectionID);
   if (squad && !squad->isDeployed)
   {
      squad->stats = stats;
      InventoryButton *b = mButtonMap.value(mSelectionID);
      if (b)
      {
         b->setEntityStats(stats);
         return true;
      }
   }
   return false;
}


EntitySquadType* Inventory::selection()
{
   return mSquadMap.value(mSelectionID);
}


void Inventory::repositionButtons()
{
   quint32 buttonCount = 0;
   int r=0, c=0;
   foreach (InventoryButton *ib, mButtonMap)
   {
      r = (buttonCount/(width()/BUTTON_SIZE)) * BUTTON_SIZE;
      c = (buttonCount%(width()/BUTTON_SIZE)) * BUTTON_SIZE;
      buttonCount++;
      ib->setGeometry(c,r,BUTTON_SIZE,BUTTON_SIZE);
   }

   // Resize widget underneath in case we need scroll bars
   setMinimumHeight(r+BUTTON_SIZE);
}


bool Inventory::hasSelection()
{
   return (mSelectionID > 0);
}

void Inventory::tick()
{
   if (hasSelection())
   {
      // Fun little pulse animation for selections, etc
      mPulsateScale += (mPulsateCountUp) ? 0.02 : -0.02;

      if (mPulsateScale >= 1.15)
         mPulsateCountUp = false;
      else if (mPulsateScale <= 1.0)
         mPulsateCountUp = true;
      // ...Now just set the painter scale to mPulsateScale in paint()
      // Calling setScale here pulsates tower ranges, which we don't
      // really want...
      mButtonMap.value(mSelectionID)->setIconScale(mPulsateScale);
      mButtonMap.value(mSelectionID)->update();
   }
}

void Inventory::setDisabled(const quint32 id, const bool value)
{
   EntitySquadType *squad = mSquadMap.value(id);
   if (squad)
   {
      squad->isDeployed = value;
      InventoryButton *b = mButtonMap.value(id);
      if (b)
         b->setDisabled(value);
   }
}


void Inventory::setColorForAllButtons(const QColor &color)
{
   foreach (InventoryButton *ib, mButtonMap)
   {
      ib->setColor(color);
      ib->update();
   }

   foreach (EntitySquadType *squad, mSquadMap)
   {
      squad->stats.color = color.rgb();
   }
}
